#!/usr/bin/env php
<?php

declare(strict_types=1);

/**
 * Shenlink 类提供了一个简单的命令行接口，用于执行预定义的命令。
 */
class Shenlink
{
    /**
     * 存储注册的命令及其对应的处理函数。
     *
     * @var array<string, callable>
     */
    private array $commands = [];

    /**
     * 构造函数，初始化默认命令。
     */
    public function __construct()
    {
        $this->registerCommand('-h', [$this, 'handleHelpCommand']);
        $this->registerCommand('--help', [$this, 'handleHelpCommand']);
        $this->registerCommand('test', [$this, 'handleTestCommand']);
        $this->registerCommand('push', [$this, 'handlePushCommand']);
    }

    /**
     * 注册一个新的命令及其处理函数。
     *
     * @param string $name 命令名称。
     * @param callable $handler 处理该命令的可调用对象。
     */
    public function registerCommand(string $name, callable $handler): void
    {
        $this->commands[$name] = $handler;
    }

    /**
     * 运行指定的命令。
     *
     * @param array<string> $argv 命令行参数数组。
     */
    public function run(array $argv): void
    {
        if (count($argv) < 2) {
            $this->handleHelpCommand();
            return;
        }

        $command = $argv[1];

        if (!isset($this->commands[$command])) {
            echo "命令未找到: $command\n";
            $this->handleHelpCommand();
            return;
        }
        call_user_func($this->commands[$command]);
    }

    /**
     * 处理帮助命令，显示帮助信息。
     */
    private function handleHelpCommand(): void
    {
        $this->showHelpInfo();
    }

    /**
     * 处理测试命令，运行 PHPUnit 测试。
     */
    private function handleTestCommand(): void
    {
        $exitCode = 0;
        $this->runTestCommand($exitCode);
    }

    /**
     * 处理推送命令，先测试，测试跳过后，才会推送到 gitee 和 github 。
     */
    private function handlePushCommand(): void
    {
        $exitCode = 0;
        $this->runTestCommand($exitCode);
        if ($exitCode !== 0) {
            echo "PHPUnit tests failed. Not pushing to repositories.";
        } else {
            $this->runPushCommand('git push origin master');
            $this->runPushCommand('git push github master');
        }
    }

    /**
     * 显示可用命令的帮助信息。
     */
    private function showHelpInfo(): void
    {
        echo "可用命令:\n";
        echo "  -h, --help - 显示帮助信息\n";
        echo "  test - 运行测试\n";
    }

    /**
     * 运行 PHPUnit 执行测试
     */
    private function runTestCommand(int &$exitCode)
    {
        echo "running tests...\n";
        // 调用 PHPUnit 执行测试
        $phpunitCommand = __DIR__ . '/vendor/bin/phpunit';
        $outputs = [];
        exec($phpunitCommand, $outputs, $exitCode);
        // 显示测试输出日志
        foreach ($outputs as $output) {
            echo $output . "\n";
        }
    }

    /**
     * 运行推送命令
     */
    private function runPushCommand(string $command): void
    {
        echo "running push...\n";
        echo $command . "\n";
        $outputs = [];
        $exitCode = 0;
        exec($command, $outputs, $exitCode);
        foreach ($outputs as $output) {
            echo $output . "\n";
        }
        if ($exitCode !== 0) {
            echo "Push error：use the command: $command\n";
        }
    }
}

$shenlink = new Shenlink();
$shenlink->run($argv);